"""
Created on 2018/4/20 17:04 星期五
@author: Matt  zhuhan1401@126.com
Description: kNN进行糖尿病预测
"""

from sklearn.model_selection import KFold, cross_val_score, ShuffleSplit  # k-折叠交叉验证
from sklearn.neighbors import KNeighborsClassifier, RadiusNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import SelectKBest
import matplotlib.pyplot as plt
from commonTool.plotCurve import plot_learning_curve
import pandas as pd

# 加载数据
data = pd.read_csv('diabetes.csv')
print('dataset shape {}'.format(data.shape))

# 分隔数据
X = data.iloc[:, 0:8]
Y = data.iloc[:, 8]
print('shape of X {};shape of Y {}'.format(X.shape, Y.shape))
XTrain, XTest, YTrain, YTest = train_test_split(X, Y, test_size=0.2)

""""

# 构造三个模型  最终选择了普通knn
models=[]
models.append(("kNN",KNeighborsClassifier(n_neighbors=2)))
models.append(("kNN with weights",KNeighborsClassifier(n_neighbors=2,weights="distance"))) # 越近的影响越大
models.append(("Radius Neighbors",RadiusNeighborsClassifier(n_neighbors=2,radius=500.0))) # 越近的影响越大

# 实际上直接测试缺乏准确性，随机划分的训练样本和测试样本可能有不同的结果 所以使用多次随机分配训练数据集和交叉验证数据集
results=[]
for name,model in models:
    kfold=KFold(n_splits=10)# 将数据集分为10份 1份作为交叉验证数据集
    cvResult=cross_val_score(model,X,Y,cv=kfold)
    results.append((name,cvResult))
for i in range(len(results)):
    print("name:{};crossValScore :{}".format(results[i][0],results[i][1]))

"""

clf=KNeighborsClassifier(n_neighbors=2)
cv=ShuffleSplit(n_splits=10,test_size=0.2,random_state=0)
plt.figure(figsize=(10,6),dpi=200)
plot_learning_curve(clf,"Learn Curve for KNN Diabetes",X,Y,ylim=(0.0,1.01),cv=cv)
# plt.show()# 描绘学习曲线 据图知 训练样本评分较低 测试样本与训练样本距离较大 为欠拟合！

# 那如何判断某种算法是不是针对此的一种好模型？？
# 其中一个办法是把数据画出来---8个特征无法全部表示则选择两个与输出值相关性最大的特征
selector=SelectKBest(k=2)
XNew=selector.fit_transform(X, Y)  # 根据卡方分布
print(XNew[:5])

# 根据这两个特征(血糖浓度和BMI)画出数据
plt.figure(figsize=(10,6),dpi=200)
plt.ylabel("BMI")
plt.xlabel("Glucose") # 血糖浓度
plt.scatter(XNew[Y==0][:,0],XNew[Y==0][:,1],c='r',s=20,marker='o')
plt.scatter(XNew[Y==1][:,0],XNew[Y==1][:,1],c='g',s=20,marker='^')
plt.show()








